/**
 * @p.md
 * 
 * FileSystemProvider 是一个基于文件系统的持久化提供者，将事件和快照存储在文件中
 */
import * as fs from 'fs';
import * as path from 'path';
import { PersistenceProvider } from './persistenceProvider';

/**
 * 存储项
 */
interface StorageItem {
  index: number;
  data: any;
  timestamp: number;
}

/**
 * 文件系统持久化提供者，用于将事件和快照持久化到文件系统
 */
export class FileSystemProvider implements PersistenceProvider {
  private basePath: string;
  private eventsDir: string;
  private snapshotsDir: string;
  
  /**
   * 构造函数
   * @param basePath 基础路径，默认为 './persistence'
   */
  constructor(basePath: string = './persistence') {
    this.basePath = basePath;
    this.eventsDir = path.join(basePath, 'events');
    this.snapshotsDir = path.join(basePath, 'snapshots');
    
    // 确保目录存在
    this.ensureDirectories();
  }
  
  /**
   * 确保必要的目录存在
   */
  private ensureDirectories(): void {
    if (!fs.existsSync(this.basePath)) {
      fs.mkdirSync(this.basePath, { recursive: true });
    }
    
    if (!fs.existsSync(this.eventsDir)) {
      fs.mkdirSync(this.eventsDir, { recursive: true });
    }
    
    if (!fs.existsSync(this.snapshotsDir)) {
      fs.mkdirSync(this.snapshotsDir, { recursive: true });
    }
  }
  
  /**
   * 获取事件文件路径
   * @param persistenceId 持久化 ID
   * @returns 文件路径
   */
  private getEventsFilePath(persistenceId: string): string {
    return path.join(this.eventsDir, `${persistenceId}.json`);
  }
  
  /**
   * 获取快照文件路径
   * @param persistenceId 持久化 ID
   * @returns 文件路径
   */
  private getSnapshotsFilePath(persistenceId: string): string {
    return path.join(this.snapshotsDir, `${persistenceId}.json`);
  }
  
  /**
   * 从文件读取存储项
   * @param filePath 文件路径
   * @returns 存储项数组
   */
  private readFromFile(filePath: string): StorageItem[] {
    if (!fs.existsSync(filePath)) {
      return [];
    }
    
    try {
      const content = fs.readFileSync(filePath, 'utf8');
      return JSON.parse(content);
    } catch (error) {
      console.error(`Error reading from ${filePath}:`, error);
      return [];
    }
  }
  
  /**
   * 写入存储项到文件
   * @param filePath 文件路径
   * @param items 存储项数组
   */
  private writeToFile(filePath: string, items: StorageItem[]): void {
    try {
      fs.writeFileSync(filePath, JSON.stringify(items, null, 2), 'utf8');
    } catch (error) {
      console.error(`Error writing to ${filePath}:`, error);
      throw error;
    }
  }
  
  /**
   * 获取指定持久化 ID 的事件
   * @param persistenceId 持久化 ID
   * @param fromIndex 开始索引（包含）
   * @param toIndex 结束索引（包含）
   * @returns 事件数组
   */
  async getEventsByPersistenceId(persistenceId: string, fromIndex: number, toIndex: number): Promise<any[]> {
    const filePath = this.getEventsFilePath(persistenceId);
    const events = this.readFromFile(filePath);
    
    return events
      .filter(e => e.index >= fromIndex && e.index <= toIndex)
      .sort((a, b) => a.index - b.index)
      .map(e => e.data);
  }
  
  /**
   * 获取指定持久化 ID 的最新快照
   * @param persistenceId 持久化 ID
   * @returns 快照数据，如果不存在则返回 null
   */
  async getSnapshotByPersistenceId(persistenceId: string): Promise<any | null> {
    const filePath = this.getSnapshotsFilePath(persistenceId);
    const snapshots = this.readFromFile(filePath);
    
    if (snapshots.length === 0) {
      return null;
    }
    
    // 排序快照，获取最新的一个
    const latestSnapshot = [...snapshots]
      .sort((a, b) => b.index - a.index)[0];
    
    return latestSnapshot ? latestSnapshot.data : null;
  }
  
  /**
   * 持久化事件
   * @param persistenceId 持久化 ID
   * @param eventIndex 事件索引
   * @param event 事件数据
   */
  async persistEvent(persistenceId: string, eventIndex: number, event: any): Promise<void> {
    const filePath = this.getEventsFilePath(persistenceId);
    const events = this.readFromFile(filePath);
    
    events.push({
      index: eventIndex,
      data: event,
      timestamp: Date.now()
    });
    
    this.writeToFile(filePath, events);
  }
  
  /**
   * 持久化快照
   * @param persistenceId 持久化 ID
   * @param snapshotIndex 快照索引
   * @param snapshot 快照数据
   */
  async persistSnapshot(persistenceId: string, snapshotIndex: number, snapshot: any): Promise<void> {
    const filePath = this.getSnapshotsFilePath(persistenceId);
    const snapshots = this.readFromFile(filePath);
    
    snapshots.push({
      index: snapshotIndex,
      data: snapshot,
      timestamp: Date.now()
    });
    
    this.writeToFile(filePath, snapshots);
  }
  
  /**
   * 删除事件
   * @param persistenceId 持久化 ID
   * @param fromIndex 开始索引（包含）
   * @param toIndex 结束索引（包含）
   */
  async deleteEvents(persistenceId: string, fromIndex: number, toIndex: number): Promise<void> {
    const filePath = this.getEventsFilePath(persistenceId);
    
    if (!fs.existsSync(filePath)) {
      return;
    }
    
    const events = this.readFromFile(filePath);
    const filteredEvents = events.filter(e => e.index < fromIndex || e.index > toIndex);
    this.writeToFile(filePath, filteredEvents);
  }
  
  /**
   * 删除快照
   * @param persistenceId 持久化 ID
   * @param fromIndex 开始索引（包含）
   * @param toIndex 结束索引（包含）
   */
  async deleteSnapshots(persistenceId: string, fromIndex: number, toIndex: number): Promise<void> {
    const filePath = this.getSnapshotsFilePath(persistenceId);
    
    if (!fs.existsSync(filePath)) {
      return;
    }
    
    const snapshots = this.readFromFile(filePath);
    const filteredSnapshots = snapshots.filter(s => s.index < fromIndex || s.index > toIndex);
    this.writeToFile(filePath, filteredSnapshots);
  }
} 